﻿using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Sustainalytics.ClientDW.DataAccessLayer;
using Sustainalytics.GCCS.DataAccessLayer;
using System.Collections.Generic;
using Sustainalytics.ClientDW.Entities;
using Sustainalytics.Synchronization.Interface;
using MongoDB.Driver;
using MongoDB.Driver.Linq;

namespace Sustainalytics.ClientDW.Synchronization.Tests
{

    public class GlobalCompactSyncTests
    {
        private const string ConnectionString = "mongodb://localhost:27017/ClientDWTests";
        private IMongoDatabase _database;

        private static List<GCCompanyProfile> _companyProfiles;
        private static List<GCOverallCompanySummary> _overallCompaniesSummary;
        private static List<GCPrincipleSummaryExtended> _principlesSummary;
        private static List<GCPrincipleEventIndicatorExtended> _principleEventIndicators;
        private static List<GCSource> _sources;

        private static void SetupFakeData()
        {
            _companyProfiles = new List<GCCompanyProfile>
            {
                new GCCompanyProfile
                {
                    Id = new Guid("00000001-0000-0000-0000-000000000000"),
                    Name = "Company 1",
                    Country = "Country 1",
                    Industry = "Industry 1",
                    MainIsin = "ISIN 1",
                    MainSedol = "Sedol 1",
                    MainExchange = "Exchange 1",
                    MainTicker = "Ticker 1"
                }
            };

            _overallCompaniesSummary = new List<GCOverallCompanySummary>
            {
                new GCOverallCompanySummary
                {
                    Id = new Guid("00000001-0000-0000-0000-000000000000"),
                    CompanyProfile = null,
                    GCSignatorySince = new DateTime(2014, 1, 1),
                    OverallCompanyAssessment = GCAssessment.NonCompliant,
                    OverallCompanyAssessmentEffectiveSince = new DateTime(2014, 1, 1),
                    LastUpdated = new DateTime(2014, 1, 1)
                }
            };

            _principlesSummary = new List<GCPrincipleSummaryExtended>
            {
                new GCPrincipleSummaryExtended
                {
                    Id = new Guid("00000001-0000-0000-0000-000000000000"),
                    CompanyId = new Guid("00000001-0000-0000-0000-000000000000"),
                    Issue = "Issue 1",
                    Principle = new GCPrincipleTemplate
                    {
                        Id = 1,
                        Name = "Principle 1",
                        Description = "Principle Description 1",
                        Pillar = new GCPillarTemplate
                        {
                            Id = 1,
                            Name = "Pillar 1"
                        }
                    },
                    PrincipleAssessment = GCAssessment.NonCompliant,
                    PrincipleAssessmentEffectiveSince = new DateTime(2014, 1, 1),
                    AssessmentSummaryAndConclusionIntroductionSentence = "Conclusion Introduction Sentence",
                    AssessmentComments = new List<string>
                    {
                        "Assessment Comment 1",
                        "Assessment Comment 2",
                        "Assessment Comment 3",
                        "Assessment Comment 4",
                        "Assessment Comment 5",
                        "Assessment Comment 6",
                    }
                },
                new GCPrincipleSummaryExtended
                {
                    Id = new Guid("00000002-0000-0000-0000-000000000000"),
                    CompanyId = new Guid("00000001-0000-0000-0000-000000000000"),
                    Issue = "Issue 2",
                    Principle = new GCPrincipleTemplate
                    {
                        Id = 2,
                        Name = "Principle 2",
                        Description = "Principle Description 2",
                        Pillar = new GCPillarTemplate
                        {
                            Id = 1,
                            Name = "Pillar 1"
                        }
                    },
                    PrincipleAssessment = GCAssessment.NonCompliant,
                    PrincipleAssessmentEffectiveSince = new DateTime(2014, 1, 1),
                    AssessmentSummaryAndConclusionIntroductionSentence = "Conclusion Introduction Sentence",
                    AssessmentComments = new List<string>
                    {
                        "Assessment Comment 1",
                        "Assessment Comment 2",
                        "Assessment Comment 3",
                        "Assessment Comment 4",
                        "Assessment Comment 5",
                        "Assessment Comment 6",
                    }
                }
            };

            _principleEventIndicators = new List<GCPrincipleEventIndicatorExtended>
            {
                new GCPrincipleEventIndicatorExtended
                {
                    Id = new Guid("00000001-0000-0000-0000-000000000000"),
                    CompanyId = new Guid("00000001-0000-0000-0000-000000000000"),
                    PrincipleTemplateId = 1,
                    IssueType = "IssueType 1",
                    EventIndicatorAssessment = GCAssessment.NonCompliant,
                    EventSummary = "Event Summary",
                    ImpactSummary = "Impact Summary",
                    ImpactComments = new List<string>
                    {
                        "Impact Comment 1",
                        "Impact Comment 2",
                        "Impact Comment 3",
                        "Impact Comment 4",
                        "Impact Comment 5",
                    },
                    ManagementSummary = "Management Summary",
                    ManagementComments = new List<string>
                    {
                        "Management Comment 1",
                        "Management Comment 2",
                        "Management Comment 3",
                        "Management Comment 4",
                        "Management Comment 5",
                    }
                },
                new GCPrincipleEventIndicatorExtended
                {
                    Id = new Guid("00000002-0000-0000-0000-000000000000"),
                    CompanyId = new Guid("00000001-0000-0000-0000-000000000000"),
                    PrincipleTemplateId = 2,
                    IssueType = "IssueType 2",
                    EventIndicatorAssessment = GCAssessment.NonCompliant,
                    EventSummary = "Event Summary",
                    ImpactSummary = "Impact Summary",
                    ImpactComments = new List<string>
                    {
                        "Impact Comment 1",
                        "Impact Comment 2",
                        "Impact Comment 3",
                        "Impact Comment 4",
                        "Impact Comment 5",
                    },
                    ManagementSummary = "Management Summary",
                    ManagementComments = new List<string>
                    {
                        "Management Comment 1",
                        "Management Comment 2",
                        "Management Comment 3",
                        "Management Comment 4",
                        "Management Comment 5",
                    }
                }
            };

            _sources = new List<GCSource>();
        }

        [TestInitialize]
        public void Initialize()
        {
            var url = MongoUrl.Create(ConnectionString);

            if (string.IsNullOrWhiteSpace(url.DatabaseName))
                throw new ArgumentException("No database specified in the connection string!");

            var client = new MongoClient(url);
            _database = client.GetDatabase(url.DatabaseName);

            SetupFakeData();
        }

        [TestMethod]
        public void GlobalCompactSyncTest()
        {
            var gcDataReader = new Mock<IGCCSDataReader>();
            gcDataReader.Setup(x => x.GetOverallCompaniesSummary()).Returns(_overallCompaniesSummary);
            gcDataReader.Setup(x => x.GetPrinciplesSummaryExtended()).Returns(_principlesSummary);
            gcDataReader.Setup(x => x.GetPrincipleEventIndicators()).Returns(_principleEventIndicators);
            gcDataReader.Setup(x => x.GetSources()).Returns(_sources);

            var gcRepository = ClientDWGlobalCompactRepository.GetInstance(ConnectionString);

            var gcSync = GlobalCompactSyncStep.GetInstance(gcRepository, gcDataReader.Object);

            var syncContext = new SyncContext
            {
                GAConnectionStrings = null,
                PreviousChanges = new List<ChangedElement>()
            };

            gcSync.Start(syncContext);

            var gcOverallCompanySummaryCollection = _database.GetCollection<GCOverallCompanySummary>(typeof(GCOverallCompanySummary).Name).AsQueryable().ToList();
            var gcOverallCompanySummaryExtendedCollection = _database.GetCollection<GCOverallCompanySummaryExtended>(typeof(GCOverallCompanySummaryExtended).Name).AsQueryable().ToList();
            var gcPrincipleConclusionCollection = _database.GetCollection<GCPrincipleConclusion>(typeof(GCPrincipleConclusion).Name).AsQueryable().ToList();
            var gcPrincipleEventIndicatorCollection = _database.GetCollection<GCPrincipleEventIndicator>(typeof(GCPrincipleEventIndicator).Name).AsQueryable().ToList();
            var gcPrincipleEventIndicatorExtendedCollection = _database.GetCollection<GCPrincipleEventIndicatorExtended>(typeof(GCPrincipleEventIndicatorExtended).Name).AsQueryable().ToList();

            Assert.IsNotNull(gcOverallCompanySummaryCollection, "GCOverallCompanySummary collection is null.");
            Assert.IsNotNull(gcOverallCompanySummaryExtendedCollection, "GCOverallCompanySummaryExtended collection is null.");
            Assert.IsNotNull(gcPrincipleConclusionCollection, "GCPrincipleConclusion collection is null.");
            Assert.IsNotNull(gcPrincipleEventIndicatorCollection, "GCPrincipleEventIndicator collection is null.");
            Assert.IsNotNull(gcPrincipleEventIndicatorExtendedCollection, "GCPrincipleEventIndicatorExtended collection is null.");

        }
    }
}
